package com.pearl.utils;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateUtils {

  public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ISO_DATE_TIME;

  public static void setDate(PreparedStatement ps, int index, Date value) throws SQLException {
    if (value == null) {
      ps.setNull(index, java.sql.Types.TIMESTAMP);
    } else {
      ps.setTimestamp(index, new java.sql.Timestamp(value.getTime()));
    }
  }

  public static void setDateTz(PreparedStatement ps, int index, Date value) throws SQLException {
    if (value == null) {
      ps.setNull(index, java.sql.Types.TIMESTAMP);
    } else {
      ps.setTimestamp(index,
          new java.sql.Timestamp(value.getTime() - TimeZone.getDefault().getRawOffset()));
    }
  }

  public static void setDateTz(PreparedStatement ps, int index, LocalDateTime value)
      throws SQLException {
    if (value == null) {
      ps.setNull(index, java.sql.Types.TIMESTAMP);
    } else {
      // 将LocalDateTime转换为Instant
      Instant instant = value.atZone(ZoneId.systemDefault()).toInstant();

      // 获取时间戳（秒）
      long timestamp = instant.getEpochSecond();
      ps.setTimestamp(index,
          new java.sql.Timestamp(timestamp - TimeZone.getDefault().getRawOffset()));
    }
  }

  public static Date getDate(ResultSet rs, int index) throws SQLException {
    if (rs.getObject(index) == null) {
      return null;
    }
    return new Date(rs.getTimestamp(index).getTime());
  }

//  public static Date getDateTz(ResultSet rs, int index) throws SQLException {
//    if (rs.getObject(index) == null) {
//      return null;
//    }
//    return new Date(rs.getTimestamp(index).getTime() + TimeZone.getDefault().getRawOffset());
//  }

  public static LocalDateTime getDateTz(ResultSet rs, int index) throws SQLException {
    if (rs.getObject(index) == null) {
      return null;
    }
    // 获取Timestamp对象
    java.sql.Timestamp timestamp = rs.getTimestamp(index);
    // 如果Timestamp为null，返回null
    if (timestamp == null) {
      return null;
    }
    // 考虑时区偏移量，将Timestamp转换为Instant
    Instant instant = timestamp.toInstant();
    // 获取系统默认时区的偏移量
    ZoneId zoneId = ZoneId.systemDefault();
    ZoneOffset zoneOffset = zoneId.getRules().getOffset(Instant.now());
    // 使用偏移量创建OffsetDateTime
    OffsetDateTime offsetDateTime = instant.atOffset(zoneOffset);
    // 提取LocalDateTime部分
    LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
    return localDateTime;
  }


  //LocalDate -> Date
  public static Date asDate(LocalDate localDate) {
    return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
  }

  //LocalDateTime -> Date
  public static Date asDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }

  //Date -> LocalDate
  public static LocalDate asLocalDate(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
  }

  //Date -> LocalDateTime
  public static LocalDateTime asLocalDateTime(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
  }

  public static String format(Date date) {
    return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
  }

  /**
   * 计算 给定时间 和 当前时间 的 差距  分钟
   */
  public static Long calculateTimeOffSet(Date date) {
    LocalDateTime start =
        LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
    LocalDateTime end = LocalDateTime.now();
    //between的用法是end-start的时间，若start的时间大于end的时间，则所有的值是负的
    Duration duration = Duration.between(start, end);
    return duration.toMinutes();
  }

  /**
   * 计算 给定时间 和 当前时间 的 差距  小时
   */
  public static Long calculateTimeOffSet(Date startDate, Date endDate) {
    LocalDateTime start =
        LocalDateTime.ofInstant(Instant.ofEpochMilli(startDate.getTime()), ZoneId.systemDefault());
    LocalDateTime end =
        LocalDateTime.ofInstant(Instant.ofEpochMilli(endDate.getTime()), ZoneId.systemDefault());
    //between的用法是end-start的时间，若start的时间大于end的时间，则所有的值是负的
    Duration duration = Duration.between(start, end);
    return duration.toHours();
  }

  public static Date dateAfterDate(int dateCount) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(new Date());
    System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//今天的日期
    calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + dateCount);//让日期加1
    return calendar.getTime();

  }


  public static Date dateAfterDate(Date date, int dateCount) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//今天的日期
    calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + dateCount);//让日期加1
    return calendar.getTime();
  }

  public static Date dateAfterMin(int minCount) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(new Date());
    System.out.println(calendar.get(Calendar.MINUTE));//今天的日期
    calendar.add(Calendar.MINUTE, minCount);//让日期加分钟
    return calendar.getTime();

  }

  /**
   * 计算 给定时间 和 当前时间 的 差距  分钟
   */
  public static Long calculateTimeOffSet2(Date startDate, Date endDate) {
    LocalDateTime start =
        LocalDateTime.ofInstant(Instant.ofEpochMilli(startDate.getTime()), ZoneId.systemDefault());
    LocalDateTime end =
        LocalDateTime.ofInstant(Instant.ofEpochMilli(endDate.getTime()), ZoneId.systemDefault());
    //between的用法是end-start的时间，若start的时间大于end的时间，则所有的值是负的
    Duration duration = Duration.between(start, end);
    return duration.toMinutes();
  }

  /**
   * 日期 加 几月
   */
  public static Date dateAfterMonthDate(Date date, int month) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//今天的日期
    calendar.add(Calendar.MONTH, month);//让日期加1
    return calendar.getTime();
  }

  public static Date dateAfterMin(Date date, int minCount) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    System.out.println(calendar.get(Calendar.MINUTE));//今天的日期
    calendar.add(Calendar.MINUTE, minCount);//让日期加分钟
    return calendar.getTime();

  }

  public static Long calculateTimeOffSetMin(Date startDate, Date endDate) {
    LocalDateTime start =
        LocalDateTime.ofInstant(Instant.ofEpochMilli(startDate.getTime()), ZoneId.systemDefault());
    LocalDateTime end =
        LocalDateTime.ofInstant(Instant.ofEpochMilli(endDate.getTime()), ZoneId.systemDefault());
    //between的用法是end-start的时间，若start的时间大于end的时间，则所有的值是负的
    Duration duration = Duration.between(start, end);
    return duration.toMinutes();
  }


  public static int getMonthDifference(Date startDate, Date endDate) {
    LocalDate start = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    LocalDate end = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    Period period = Period.between(start, end);
    int months = period.getYears() * 12 + period.getMonths();
    return months;
  }

}
